start_kernel part X
Continue routine vfs_caches_init
of start_kernel part IX
Involves routine
mnt_init
, which allocates slab cache for structvfsmount
namedmnt_cache
, gets free pages formount_hashtable
and initializes it, registerssysfs
, this is needed later for actually finding root device, registersrootfs
, creates the initial filesystem namespace, with rootfs mounted at/
Let's check more about
sysfs_init
,init_rootfs
andinit_mount_tree
With
sysfs_init
to learn how a new file system mounted to kernel, debug information of the function shown as below
(gdb) break sysfs_init
Breakpoint 6 at 0xc1717b35: file fs/sysfs/mount.c, line 89.
(gdb) c
Continuing.
Breakpoint 6, sysfs_init () at fs/sysfs/mount.c:89
89 {
(gdb) n
92 sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache",
(gdb)
95 if (!sysfs_dir_cachep)
(gdb)
98 err = sysfs_inode_init();
(gdb) s
sysfs_inode_init () at fs/sysfs/inode.c:46
46 return bdi_init(&sysfs_backing_dev_info);
(gdb) s
bdi_init (bdi=bdi@entry=0xc16ac140 <sysfs_backing_dev_info>)
at mm/backing-dev.c:660
660 spin_lock_init(&bdi->wb_lock);
(gdb) n
652 {
(gdb)
655 bdi->dev = NULL;
(gdb)
657 bdi->min_ratio = 0;
(gdb)
658 bdi->max_ratio = 100;
(gdb)
659 bdi->max_prop_frac = PROP_FRAC_BASE;
(gdb)
660 spin_lock_init(&bdi->wb_lock);
(gdb) s
__spin_lock_init (
lock=lock@entry=0xc16ac284 <sysfs_backing_dev_info+324>,
name=name@entry=0xc15ece57 "&bdi->wb_lock",
key=key@entry=0xc1e5c9e8 <__key.22236>)
at lib/spinlock_debug.c:23
23 debug_check_no_locks_freed((void *)lock, sizeof(*lock));
(gdb) n
24 lockdep_init_map(&lock->dep_map, name, key, 0);
(gdb)
26 lock->raw_lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
(gdb)
27 lock->magic = SPINLOCK_MAGIC;
(gdb)
28 lock->owner = SPINLOCK_OWNER_INIT;
(gdb)
29 lock->owner_cpu = -1;
(gdb)
30 }
(gdb)
bdi_init (bdi=bdi@entry=0xc16ac140 <sysfs_backing_dev_info>)
at mm/backing-dev.c:661
661 INIT_RCU_HEAD(&bdi->rcu_head);
(gdb)
662 INIT_LIST_HEAD(&bdi->bdi_list);
(gdb)
663 INIT_LIST_HEAD(&bdi->wb_list);
(gdb)
664 INIT_LIST_HEAD(&bdi->work_list);
(gdb)
666 bdi_wb_init(&bdi->wb, bdi);
(gdb)
671 bdi->wb_mask = 1;
(gdb)
672 bdi->wb_cnt = 1;
(gdb)
675 err = percpu_counter_init(&bdi->bdi_stat[i], 0);
(gdb) p i
$10 = 1
(gdb) n
676 if (err)
(gdb)
680 bdi->dirty_exceeded = 0;
(gdb)
681 err = prop_local_init_percpu(&bdi->completions);
(gdb)
685 while (i--)
(gdb) p err
$12 = 0
(gdb) n
690 }
(gdb)
sysfs_inode_init () at fs/sysfs/inode.c:47
47 }
(gdb)
sysfs_init () at fs/sysfs/mount.c:99
99 if (err)
(gdb)
102 err = register_filesystem(&sysfs_fs_type);
(gdb) p sysfs_fs_type
$13 = {name = 0xc1616401 "sysfs", fs_flags = 0,
get_sb = 0xc11716c0 <sysfs_get_sb>,
kill_sb = 0xc1115230 <kill_anon_super>, owner = 0x0, next = 0x0,
fs_supers = {next = 0x0, prev = 0x0}, s_lock_key = {subkeys = {{
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}}},
s_umount_key = {subkeys = {{__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}}}, i_lock_key = {subkeys = {{
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}}},
i_mutex_key = {subkeys = {{__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}}}, i_mutex_dir_key = {subkeys = {{
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
---Type <return> to continue, or q <return> to quit---
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}}},
i_alloc_sem_key = {subkeys = {{__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}}}}
(gdb) s
register_filesystem (fs=fs@entry=0xc16ac520 <sysfs_fs_type>)
at fs/filesystems.c:74
74 BUG_ON(strchr(fs->name, '.'));
(gdb) n
75 if (fs->next)
(gdb)
77 INIT_LIST_HEAD(&fs->fs_supers);
(gdb)
78 write_lock(&file_systems_lock);
(gdb)
79 p = find_filesystem(fs->name, strlen(fs->name));
(gdb) s
strlen (s=0xc1616401 "sysfs") at arch/x86/lib/string_32.c:168
168 asm volatile("repne\n\t"
(gdb) n
176 }
(gdb) s
find_filesystem (name=0xc1616401 "sysfs", len=5)
at fs/filesystems.c:49
49 for (p=&file_systems; *p; p=&(*p)->next)
(gdb) n
54 }
(gdb)
register_filesystem (fs=fs@entry=0xc16ac520 <sysfs_fs_type>)
at fs/filesystems.c:80
80 if (*p)
(gdb)
83 *p = fs;
(gdb)
71 int res = 0;
(gdb)
84 write_unlock(&file_systems_lock);
(gdb)
85 return res;
(gdb)
86 }
(gdb)
sysfs_init () at fs/sysfs/mount.c:103
103 if (!err) {
(gdb) p file_systems
$14 = (struct file_system_type *) 0xc16ac520 <sysfs_fs_type>
(gdb) p file_systems->next
$15 = (struct file_system_type *) 0x0
104 sysfs_mount = kern_mount(&sysfs_fs_type);
(gdb) s
kern_mount_data (type=type@entry=0xc16ac520 <sysfs_fs_type>,
data=data@entry=0x0) at fs/super.c:1016
1016 return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
(gdb) s
vfs_kern_mount (type=type@entry=0xc16ac520 <sysfs_fs_type>,
flags=flags@entry=4194304, name=0xc1616401 "sysfs",
data=data@entry=0x0) at fs/super.c:920
920 if (!type)
(gdb) n
924 mnt = alloc_vfsmnt(name);
(gdb) s
alloc_vfsmnt (name=name@entry=0xc1616401 "sysfs")
at fs/namespace.c:130
130 struct vfsmount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
(gdb) n
131 if (mnt) {
(gdb)
134 err = mnt_alloc_id(mnt);
(gdb)
138 if (name) {
(gdb)
139 mnt->mnt_devname = kstrdup(name, GFP_KERNEL);
(gdb)
140 if (!mnt->mnt_devname)
(gdb)
144 atomic_set(&mnt->mnt_count, 1);
(gdb)
145 INIT_LIST_HEAD(&mnt->mnt_hash);
(gdb)
146 INIT_LIST_HEAD(&mnt->mnt_child);
(gdb)
147 INIT_LIST_HEAD(&mnt->mnt_mounts);
(gdb)
148 INIT_LIST_HEAD(&mnt->mnt_list);
(gdb)
149 INIT_LIST_HEAD(&mnt->mnt_expire);
(gdb)
150 INIT_LIST_HEAD(&mnt->mnt_share);
(gdb)
151 INIT_LIST_HEAD(&mnt->mnt_slave_list);
(gdb)
152 INIT_LIST_HEAD(&mnt->mnt_slave);
(gdb)
154 mnt->mnt_writers = alloc_percpu(int);
(gdb)
155 if (!mnt->mnt_writers)
(gdb)
172 }
(gdb)
vfs_kern_mount (type=type@entry=0xc16ac520 <sysfs_fs_type>,
flags=flags@entry=4194304, name=0xc1616401 "sysfs",
data=data@entry=0x0) at fs/super.c:925
925 if (!mnt)
(gdb)
928 if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) {
(gdb)
938 error = type->get_sb(type, flags, name, data, mnt);
(gdb)
939 if (error < 0)
(gdb)
941 BUG_ON(!mnt->mnt_sb);
(gdb)
943 error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
(gdb) s
security_sb_kern_mount (sb=0xc7008430, flags=flags@entry=4194304,
data=data@entry=0x0) at security/security.c:273
273 return security_ops->sb_kern_mount(sb, flags, data);
(gdb) s
cap_sb_kern_mount (sb=0xc7008430, flags=4194304, data=0x0)
at security/capability.c:65
65 }
(gdb) n
security_sb_kern_mount (sb=<optimized out>,
flags=flags@entry=4194304, data=data@entry=0x0)
at security/security.c:274
274 }
(gdb)
vfs_kern_mount (type=type@entry=0xc16ac520 <sysfs_fs_type>,
flags=flags@entry=4194304, name=<optimized out>,
data=data@entry=0x0) at fs/super.c:944
944 if (error)
(gdb)
954 WARN((mnt->mnt_sb->s_maxbytes < 0), "%s set sb->s_maxbytes to "
(gdb)
957 mnt->mnt_mountpoint = mnt->mnt_root;
(gdb) p mnt->mnt_root
$16 = (struct dentry *) 0xc6c02000
(gdb) p *mnt->mnt_root
$17 = {d_count = {counter = 2}, d_flags = 16, d_lock = {raw_lock = {
slock = 514}, magic = 3735899821, owner_cpu = 4294967295,
owner = 0xffffffff, dep_map = {key = 0xc1e6248c <__key.26347>,
class_cache = 0xc1b5db20 <lock_classes+144096>,
name = 0xc15ef0b2 "&dentry->d_lock", cpu = 0,
ip = 3239351818}}, d_mounted = 0, d_inode = 0xc6c00000,
d_hash = {next = 0x0, pprev = 0x0}, d_parent = 0xc6c02000,
d_name = {hash = 0, len = 1, name = 0xc6c0207c "/"}, d_lru = {
next = 0xc6c0204c, prev = 0xc6c0204c}, d_u = {d_child = {
next = 0xc6c02054, prev = 0xc6c02054}, d_rcu = {
next = 0xc6c02054, func = 0xc6c02054}}, d_subdirs = {
next = 0xc6c0205c, prev = 0xc6c0205c}, d_alias = {
next = 0xc6c00018, prev = 0xc6c00018}, d_time = 1802201963,
d_op = 0x0, d_sb = 0xc7008430,
d_fsdata = 0xc16ac580 <sysfs_root>,
d_iname = "/\000", 'k' <repeats 37 times>, "\245"}
(gdb) n
958 mnt->mnt_parent = mnt;
(gdb)
959 up_write(&mnt->mnt_sb->s_umount);
(gdb)
960 free_secdata(secdata);
(gdb) s
free_secdata (secdata=0x0) at include/linux/security.h:3133
3133 free_page((unsigned long)secdata);
(gdb) s
free_pages (addr=addr@entry=0, order=order@entry=0)
at mm/page_alloc.c:2034
2034 if (addr != 0) {
(gdb) n
2038 }
(gdb)
vfs_kern_mount (type=type@entry=0xc16ac520 <sysfs_fs_type>,
flags=flags@entry=4194304, name=<optimized out>,
data=data@entry=0x0) at fs/super.c:961
961 return mnt;
(gdb) n
971 }
(gdb)
kern_mount_data (type=type@entry=0xc16ac520 <sysfs_fs_type>,
data=data@entry=0x0) at fs/super.c:1017
1017 }
(gdb)
sysfs_init () at fs/sysfs/mount.c:105
105 if (IS_ERR(sysfs_mount)) {
(gdb)
120 }
(gdb)
mnt_init () at fs/namespace.c:2304
2304 if (err)
Debug information of `init_rootfs` shown as follow, it just registers `rootfs`
2310 init_rootfs();
(gdb) s
init_rootfs () at fs/ramfs/inode.c:311
311 err = bdi_init(&ramfs_backing_dev_info);
(gdb) s
bdi_init (bdi=bdi@entry=0xc16ad4c0 <ramfs_backing_dev_info>)
at mm/backing-dev.c:655
(gdb) n
655 bdi->dev = NULL;
(gdb)
657 bdi->min_ratio = 0;
(gdb)
658 bdi->max_ratio = 100;
(gdb)
659 bdi->max_prop_frac = PROP_FRAC_BASE;
(gdb)
660 spin_lock_init(&bdi->wb_lock);
(gdb)
661 INIT_RCU_HEAD(&bdi->rcu_head);
(gdb)
662 INIT_LIST_HEAD(&bdi->bdi_list);
(gdb)
663 INIT_LIST_HEAD(&bdi->wb_list);
(gdb)
663 INIT_LIST_HEAD(&bdi->wb_list);
(gdb)
664 INIT_LIST_HEAD(&bdi->work_list);
(gdb)
666 bdi_wb_init(&bdi->wb, bdi);
(gdb)
666 bdi_wb_init(&bdi->wb, bdi);
(gdb)
671 bdi->wb_mask = 1;
(gdb)
672 bdi->wb_cnt = 1;
(gdb)
675 err = percpu_counter_init(&bdi->bdi_stat[i], 0);
(gdb)
676 if (err)
(gdb)
680 bdi->dirty_exceeded = 0;
(gdb)
681 err = prop_local_init_percpu(&bdi->completions);
(gdb)
683 if (err) {
(gdb)
685 while (i--)
(gdb)
690 }
(gdb)
init_rootfs () at fs/ramfs/inode.c:312
312 if (err)
(gdb)
315 err = register_filesystem(&rootfs_fs_type);
(gdb) s
register_filesystem (fs=fs@entry=0xc16ad400 <rootfs_fs_type>)
at fs/filesystems.c:74
74 BUG_ON(strchr(fs->name, '.'));
(gdb) n
75 if (fs->next)
(gdb)
77 INIT_LIST_HEAD(&fs->fs_supers);
(gdb)
81 res = -EBUSY;
(gdb)
77 INIT_LIST_HEAD(&fs->fs_supers);
(gdb)
78 write_lock(&file_systems_lock);
(gdb)
79 p = find_filesystem(fs->name, strlen(fs->name));
(gdb)
80 if (*p)
(gdb)
83 *p = fs;
(gdb)
71 int res = 0;
(gdb) p file_systems
$18 = (struct file_system_type *) 0xc16ac520 <sysfs_fs_type>
(gdb) p file_systems->next
$19 = (struct file_system_type *) 0xc16ad400 <rootfs_fs_type>
(gdb) p file_systems->next->next
$20 = (struct file_system_type *) 0x0
(gdb) n
84 write_unlock(&file_systems_lock);
(gdb)
85 return res;
(gdb)
86 }
(gdb)
init_rootfs () at fs/ramfs/inode.c:316
316 if (err)
(gdb)
320 }
(gdb)
mnt_init () at fs/namespace.c:2311
2311 init_mount_tree();
Debug information of `init_mount_tree` shown as follow
mnt_init () at fs/namespace.c:2311
2311 init_mount_tree();
(gdb) s
init_mount_tree () at fs/namespace.c:2266
2266 mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
(gdb) s
do_kern_mount (fstype=fstype@entry=0xc15ef45c "rootfs",
flags=flags@entry=0, name=name@entry=0xc15ef45c "rootfs",
data=data@entry=0x0) at fs/super.c:1000
1000 {
(gdb) n
1001 struct file_system_type *type = get_fs_type(fstype);
(gdb)
1003 if (!type)
(gdb)
1005 mnt = vfs_kern_mount(type, flags, name, data);
(gdb) p type
$21 = (struct file_system_type *) 0xc16ad400 <rootfs_fs_type>
(gdb) n
1006 if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
(gdb)
1009 put_filesystem(type);
(gdb) s
put_filesystem (fs=fs@entry=0xc16ad400 <rootfs_fs_type>)
at fs/filesystems.c:43
43 module_put(fs->owner);
(gdb) s
module_put (module=0x0) at kernel/module.c:951
951 if (module) {
(gdb) n
961 }
(gdb)
put_filesystem (fs=fs@entry=0xc16ad400 <rootfs_fs_type>)
at fs/filesystems.c:44
44 }
(gdb)
do_kern_mount (fstype=fstype@entry=0xc15ef45c "rootfs",
flags=flags@entry=0, name=name@entry=0xc15ef45c "rootfs",
data=data@entry=0x0) at fs/super.c:1010
1010 return mnt;
(gdb)
1011 }
(gdb)
init_mount_tree () at fs/namespace.c:2267
2267 if (IS_ERR(mnt))
(gdb)
2269 ns = create_mnt_ns(mnt);
(gdb) s
create_mnt_ns (mnt=0xc701d0c0) at fs/namespace.c:2079
2079 {
(gdb) n
2082 new_ns = alloc_mnt_ns();
(gdb) s
alloc_mnt_ns () at fs/namespace.c:1986
1986 new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
(gdb) n
1987 if (!new_ns)
(gdb)
1989 atomic_set(&new_ns->count, 1);
(gdb)
1990 new_ns->root = NULL;
(gdb)
1991 INIT_LIST_HEAD(&new_ns->list);
(gdb)
1992 init_waitqueue_head(&new_ns->poll);
(gdb) s
__init_waitqueue_head (q=q@entry=0xc7001240,
key=key@entry=0xc1e6266c <__key.25018>) at kernel/wait.c:15
15 spin_lock_init(&q->lock);
(gdb) n
16 lockdep_set_class(&q->lock, key);
(gdb) s
lockdep_init_map (lock=lock@entry=0xc7001250,
name=name@entry=0xc16237be "key",
key=key@entry=0xc1e6266c <__key.25018>,
subclass=subclass@entry=0) at kernel/lockdep.c:2678
2678 lock->class_cache = NULL;
(gdb) n
2680 lock->cpu = raw_smp_processor_id();
(gdb)
2683 if (DEBUG_LOCKS_WARN_ON(!name)) {
(gdb)
2688 lock->name = name;
(gdb)
2690 if (DEBUG_LOCKS_WARN_ON(!key))
(gdb)
2695 if (!static_obj(key)) {
(gdb)
2700 lock->key = key;
(gdb)
2702 if (unlikely(!debug_locks))
(gdb)
2705 if (subclass)
(gdb)
2707 }
(gdb)
__init_waitqueue_head (q=q@entry=0xc7001240,
key=key@entry=0xc1e6266c <__key.25018>) at kernel/wait.c:17
17 INIT_LIST_HEAD(&q->task_list);
(gdb)
18 }
(gdb)
alloc_mnt_ns () at fs/namespace.c:1993
1993 new_ns->event = 0;
(gdb)
1994 return new_ns;
(gdb)
1995 }
(gdb)
create_mnt_ns (mnt=0xc701d0c0) at fs/namespace.c:2083
2083 if (!IS_ERR(new_ns)) {
(gdb)
2084 mnt->mnt_ns = new_ns;
(gdb)
2085 new_ns->root = mnt;
(gdb)
2086 list_add(&new_ns->list, &new_ns->root->mnt_list);
(gdb)
2089 }
(gdb)
init_mount_tree () at fs/namespace.c:2270
2270 if (IS_ERR(ns))
(gdb)
2273 init_task.nsproxy->mnt_ns = ns;
(gdb) p ns
$22 = (struct mnt_namespace *) 0xc7001230
(gdb) p *ns
$23 = {count = {counter = 1}, root = 0xc701d0c0, list = {
next = 0xc701d0f0, prev = 0xc701d0f0}, poll = {lock = {
raw_lock = {slock = 0}, magic = 3735899821,
owner_cpu = 4294967295, owner = 0xffffffff, dep_map = {
key = 0xc1e6266c <__key.25018>, class_cache = 0x0,
name = 0xc16237be "key", cpu = 0, ip = 1802201963}},
task_list = {next = 0xc7001264, prev = 0xc7001264}}, event = 0}
(gdb) n
2274 get_mnt_ns(ns);
(gdb)
2276 root.mnt = ns->root;
(gdb)
2279 set_fs_pwd(current->fs, &root);
(gdb) s
get_current ()
at /home/start-kernel/work_space/github/linux_startup/linux-2.6.32.69/arch/x86/include/asm/current.h:14
14 return percpu_read_stable(current_task);
(gdb) n
init_mount_tree () at fs/namespace.c:2279
2279 set_fs_pwd(current->fs, &root);
(gdb) s
set_fs_pwd (fs=0xc16aa620 <init_fs>,
path=path@entry=0xc168bf88 <init_thread_union+8072>)
at fs/fs_struct.c:33
33 write_lock(&fs->lock);
(gdb) n
34 old_pwd = fs->pwd;
(gdb) p fs->pwd
$24 = {mnt = 0x0, dentry = 0x0}
(gdb) n
35 fs->pwd = *path;
(gdb) p path
$25 = (struct path *) 0xc168bf88 <init_thread_union+8072>
(gdb) n
36 path_get(path);
(gdb) p fs->pwd
$26 = {mnt = 0xc701d0c0, dentry = 0x0}
(gdb) s
path_get (path=path@entry=0xc168bf88 <init_thread_union+8072>)
at fs/namei.c:363
363 mntget(path->mnt);
(gdb) p path->mnt
$27 = (struct vfsmount *) 0xc701d0c0
(gdb) p path->mnt->mnt_count
$28 = {counter = 1}
(gdb) n
364 dget(path->dentry);
(gdb) p path->mnt->mnt_count
$29 = {counter = 2}
(gdb) s
dget (dentry=0xc6c020d0) at include/linux/dcache.h:335
335 if (dentry) {
(gdb) n
336 BUG_ON(!atomic_read(&dentry->d_count));
(gdb)
337 atomic_inc(&dentry->d_count);
(gdb)
path_get (path=path@entry=0xc168bf88 <init_thread_union+8072>)
at fs/namei.c:365
365 }
(gdb)
set_fs_pwd (fs=0xc16aa620 <init_fs>,
path=path@entry=0xc168bf88 <init_thread_union+8072>)
at fs/fs_struct.c:37
37 write_unlock(&fs->lock);
(gdb)
39 if (old_pwd.dentry)
(gdb) p old_pwd.dentry
$30 = (struct dentry *) 0x0
(gdb) n
41 }
(gdb)
init_mount_tree () at fs/namespace.c:2280
2280 set_fs_root(current->fs, &root);
(gdb) s
set_fs_root (fs=0xc16aa620 <init_fs>,
path=path@entry=0xc168bf88 <init_thread_union+8072>)
at fs/fs_struct.c:16
16 write_lock(&fs->lock);
(gdb) n
17 old_root = fs->root;
(gdb)
18 fs->root = *path;
(gdb) p fs->root
$31 = {mnt = 0x0, dentry = 0x0}
(gdb) n
19 path_get(path);
(gdb) p fs->root
$32 = {mnt = 0xc701d0c0, dentry = 0x0}
(gdb) n
20 write_unlock(&fs->lock);
(gdb)
21 if (old_root.dentry)
(gdb)
23 }
(gdb)
mnt_init () at fs/namespace.c:2312
2312 }
(gdb)
- Involves routine
bdev_cache_init
to initialize block device. Insidebdev_cache_init
, it creates slab cache for structbdev_inode
, registers file system typebd_type
and mounts the new regisgered file system, with routinekmemleak_not_leak
to tell kmemleak not to report it, finnaly initializes block device super block data. - Involves routine chrdev_init to initialize charactor device.
Breakpoint 2, chrdev_init () at fs/char_dev.c:569
569 {
(gdb) n
570 cdev_map = kobj_map_init(base_probe, &chrdevs_lock);
(gdb) s
kobj_map_init (base_probe=base_probe@entry=0xc1116760 <base_probe>,
lock=lock@entry=0xc16a7a20 <chrdevs_lock>)
at drivers/base/map.c:137
137 {
(gdb) n
138 struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL);
(gdb)
139 struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL);
(gdb)
142 if ((p == NULL) || (base == NULL)) {
(gdb)
148 base->dev = 1;
(gdb)
149 base->range = ~0;
(gdb)
150 base->get = base_probe;
(gdb)
151 for (i = 0; i < 255; i++)
(gdb)
152 p->probes[i] = base;
(gdb) break if i==254
Breakpoint 3 at 0xc12f5218: file drivers/base/map.c, line 152.
(gdb) c
Continuing.
Breakpoint 3, kobj_map_init (
base_probe=base_probe@entry=0xc1116760 <base_probe>,
lock=lock@entry=0xc16a7a20 <chrdevs_lock>)
at drivers/base/map.c:152
152 p->probes[i] = base;
(gdb) p i
$1 = 254
(gdb) n
151 for (i = 0; i < 255; i++)
(gdb)
153 p->lock = lock;
(gdb)
154 return p;
(gdb)
155 }
(gdb)
chrdev_init () at fs/char_dev.c:571
571 bdi_init(&directly_mappable_cdev_bdi);
chrdev_init () at fs/char_dev.c:572
572 }
(gdb)
vfs_caches_init (mempages=27097) at fs/dcache.c:2339
2339 }
(gdb)
start_kernel () at init/main.c:674
674 radix_tree_init();
initialize radix tree
radix_tree_init
allocates slab cache for struct radix_tree_node
, initializes max index of radix tree, registers notifier radix_tree_callback
when cpu hot plugin.
initialize signals
signals_init
just allocates slab cache for struct sigqueue
.
initialize page writeback
The linux kernel implements a primary disk cache called the page cache. The goal of this cache is to minimize disk I/O by storing in physical memory data that would otherwise be accessed from disk.
Disk caches are beneficial for two reasons. First, disk access is magnitudes slower than memory access. Accessing data from memory rather than the disk is much faster. Second, data accessed once will, with a high likelihood, find itself accessed again in the near future. This principle, that access to a particular piece of data tends to be clustered in time, is called temporal localityz.Temporal locality ensures that if data is cached on its first access, there is a high probability of a cache hit (access to data that is in the cache) in the near future.
The page cache consists of physical pages in RAM. Each page in the cache corresponds to multiple blocks on the disk. Whenever the kernel begins a page I/O operation (a disk operation in page-size chunks, usually to a regular file), it first checks whether the requisite data is in the page cache. If it is, the kernel can forego accessing the disk and use the data straight from the page cache.
Individual disk blocks can also tie into the page cache, by way of block I/O buffers. A buffer is the in-memory representation of a single physical disk block. Buffers act as descriptors that map pages in memory to disk blocks; thus, the page cache also reduces disk access during block I/O operations by both caching disk blocks and buffering block I/O operations until later. This caching is often referred to as the "buffer cache," although in reality it is not a separate cache and is part of the page cache.
page_writeback_init
is called early on to tune the page writeback dirty limits.
- Involves
writeback_set_ratelimit
to setratelimit_pages
, Ifratelimit_pages
is too high then we can get into dirty-data overload if a large number of processes all perform writes at the same time. If it is too low then SMP machines will call the (expensive)get_writeback_state
too often - Register notifier when cpu going up/down
Calculate the couple the period to the dirty_ratio
Initialzes prop_descriptor
vm_completions
andvm_dirties
page_writeback_init () at mm/page-writeback.c:801
801 shift = calc_period_shift();
(gdb)
802 prop_descriptor_init(&vm_completions, shift);
(gdb) p shift
$8 = 14
(gdb) s
prop_descriptor_init (pd=pd@entry=0xc1e5c820 <vm_completions>,
shift=shift@entry=14) at lib/proportions.c:83
83 pd->index = 0;
(gdb) n
84 pd->pg[0].shift = shift;
(gdb)
85 mutex_init(&pd->mutex);
(gdb)
86 err = percpu_counter_init(&pd->pg[0].events, 0);
(gdb)
87 if (err)
(gdb)
90 err = percpu_counter_init(&pd->pg[1].events, 0);
(gdb)
91 if (err)
(gdb)
96 }
page_writeback_init () at mm/page-writeback.c:803
803 prop_descriptor_init(&vm_dirties, shift);
(gdb) s
prop_descriptor_init (pd=pd@entry=0xc1e5c740 <vm_dirties>,
shift=shift@entry=14) at lib/proportions.c:83
83 pd->index = 0;
(gdb) n
84 pd->pg[0].shift = shift;
(gdb)
85 mutex_init(&pd->mutex);
(gdb)
86 err = percpu_counter_init(&pd->pg[0].events, 0);
(gdb)
87 if (err)
(gdb)
90 err = percpu_counter_init(&pd->pg[1].events, 0);
(gdb)
91 if (err)
(gdb)
96 }
(gdb)
page_writeback_init () at mm/page-writeback.c:804
804 }
(gdb)
start_kernel () at init/main.c:679
679 proc_root_init();
(gdb)
initialize proc file system
/proc is very special in that it is also a virtual filesystem. It's sometimes referred to as a process information pseudo-file system. It doesn't contain 'real' files but runtime system information (e.g. system memory, devices mounted, hardware configuration, etc). For this reason it can be regarded as a control and information centre for the kernel. In fact, quite a lot of system utilities are simply calls to files in this directory. For example, 'lsmod' is the same as 'cat /proc/modules' while 'lspci' is a synonym for 'cat /proc/pci'. By altering files located in this directory you can even read/change kernel parameters (sysctl) while the system is running.
proc_root_init
- Create slab caches for struct
proc_inode
namedproc_inode_cache
Breakpoint 2, proc_root_init () at fs/proc/root.c:105
105 {
(gdb) n
108 proc_init_inodecache();
(gdb) s
proc_init_inodecache () at fs/proc/inode.c:105
105 proc_inode_cachep = kmem_cache_create("proc_inode_cache",
(gdb) n
110 }
(gdb)
proc_root_init () at fs/proc/root.c:109
- Registers proc filesystem and checks the result
109 err = register_filesystem(&proc_fs_type);
(gdb) p proc_fs_type
$1 = {name = 0xc15dbf10 "proc", fs_flags = 0,
get_sb = 0xc115e4f0 <proc_get_sb>, kill_sb = 0xc115e4c0 <proc_kill_sb>,
owner = 0x0, next = 0x0, fs_supers = {next = 0x0, prev = 0x0}, s_lock_key = {
subkeys = {{__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}}}, s_umount_key = {
subkeys = {{__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}}}, i_lock_key = {
subkeys = {{__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}}}, i_mutex_key = {
subkeys = {{__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}}}, i_mutex_dir_key = {
subkeys = {{__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}}}, i_alloc_sem_key = {
---Type <return> to continue, or q <return> to quit---
subkeys = {{__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}, {
__one_byte = 0 '\000'}, {__one_byte = 0 '\000'}}}}
(gdb) n
110 if (err)
- Mounts proc filesystem and checks the result
(gdb)
112 proc_mnt = kern_mount_data(&proc_fs_type, &init_pid_ns);
(gdb)
114 if (IS_ERR(proc_mnt)) {
- Create symlink
mounts
underproc_root
for the real destination directoryself/mounts
119 proc_symlink("mounts", NULL, "self/mounts");
(gdb) s
proc_symlink (name=name@entry=0xc15f0aec "mounts", parent=parent@entry=0x0,
dest=dest@entry=0xc15f0ae7 "self/mounts") at fs/proc/generic.c:643
643 {
(gdb) n
646 ent = __proc_create(&parent, name,
(gdb) s
__proc_create (parent=parent@entry=0xc168bfa8 <init_thread_union+8104>,
name=name@entry=0xc15f0aec "mounts", mode=mode@entry=41471,
nlink=nlink@entry=1) at fs/proc/generic.c:606
606 {
(gdb) n
608 const char *fn = name;
(gdb)
612 if (!name || !strlen(name)) goto out;
(gdb)
614 if (xlate_proc_name(name, parent, &fn) != 0)
(gdb) s
xlate_proc_name (name=name@entry=0xc15f0aec "mounts",
ret=ret@entry=0xc168bfa8 <init_thread_union+8104>,
residual=residual@entry=0xc168bf8c <init_thread_union+8076>)
at fs/proc/generic.c:302
302 de = *ret;
(gdb) n
304 de = &proc_root;
(gdb)
306 spin_lock(&proc_subdir_lock);
(gdb)
308 next = strchr(cp, '/');
(gdb)
309 if (!next)
(gdb)
323 *residual = cp;
(gdb)
324 *ret = de;
(gdb)
326 spin_unlock(&proc_subdir_lock);
(gdb)
328 }
(gdb) p residual
$2 = (const char **) 0xc168bf8c <init_thread_union+8076>
(gdb) p *residual
$3 = 0xc15f0aec "mounts"
(gdb) p ret
$4 = (struct proc_dir_entry **) 0xc168bfa8 <init_thread_union+8104>
(gdb) p *ret
$5 = (struct proc_dir_entry *) 0xc16abe20 <proc_root>
(gdb) n
__proc_create (parent=parent@entry=0xc168bfa8 <init_thread_union+8104>,
name=name@entry=0xc15f0aec "mounts", mode=mode@entry=41471,
nlink=nlink@entry=1) at fs/proc/generic.c:618
618 if (strchr(fn, '/'))
(gdb)
621 len = strlen(fn);
(gdb)
623 ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
(gdb) p len
$6 = 6
(gdb) n
624 if (!ent) goto out;
(gdb)
626 memset(ent, 0, sizeof(struct proc_dir_entry));
(gdb)
627 memcpy(((char *) ent) + sizeof(struct proc_dir_entry), fn, len + 1);
(gdb)
628 ent->name = ((char *) ent) + sizeof(*ent);
(gdb)
629 ent->namelen = len;
(gdb)
630 ent->mode = mode;
(gdb)
631 ent->nlink = nlink;
(gdb)
632 atomic_set(&ent->count, 1);
(gdb)
633 ent->pde_users = 0;
(gdb)
634 spin_lock_init(&ent->pde_unload_lock);
(gdb)
635 ent->pde_unload_completion = NULL;
(gdb)
636 INIT_LIST_HEAD(&ent->pde_openers);
(gdb)
639 }
(gdb) p ent
$7 = (struct proc_dir_entry *) 0xc701f420
(gdb) p *ent
$8 = {low_ino = 0, namelen = 6, name = 0xc701f498 "mounts", mode = 41471,
nlink = 1, uid = 0, gid = 0, size = 0, proc_iops = 0x0, proc_fops = 0x0,
next = 0x0, parent = 0x0, subdir = 0x0, data = 0x0, read_proc = 0x0,
write_proc = 0x0, count = {counter = 1}, pde_users = 0, pde_unload_lock = {
raw_lock = {slock = 0}, magic = 3735899821, owner_cpu = 4294967295,
owner = 0xffffffff, dep_map = {key = 0xc1e62b00 <__key.14684>,
class_cache = 0x0, name = 0xc15f0d6f "&ent->pde_unload_lock", cpu = 0,
ip = 0}}, pde_unload_completion = 0x0, pde_openers = {next = 0xc701f490,
prev = 0xc701f490}}
(gdb) n
639 }
(gdb)
proc_symlink (name=name@entry=0xc15f0aec "mounts",
parent=0xc16abe20 <proc_root>, parent@entry=0x0,
dest=dest@entry=0xc15f0ae7 "self/mounts") at fs/proc/generic.c:649
649 if (ent) {
(gdb)
650 ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
(gdb)
651 if (ent->data) {
(gdb)
652 strcpy((char*)ent->data,dest);
(gdb)
653 if (proc_register(parent, ent) < 0) {
(gdb) s
proc_register (dir=0xc16abe20 <proc_root>, dp=dp@entry=0xc701f420)
at fs/proc/generic.c:560
560 {
(gdb) n
564 i = get_inode_number();
(gdb)
569 if (S_ISDIR(dp->mode)) {
(gdb)
575 } else if (S_ISLNK(dp->mode)) {
(gdb)
576 if (dp->proc_iops == NULL)
(gdb)
577 dp->proc_iops = &proc_link_inode_operations;
(gdb)
585 spin_lock(&proc_subdir_lock);
(gdb)
587 for (tmp = dir->subdir; tmp; tmp = tmp->next)
(gdb)
594 dp->next = dir->subdir;
(gdb)
595 dp->parent = dir;
(gdb)
596 dir->subdir = dp;
(gdb)
597 spin_unlock(&proc_subdir_lock);
(gdb)
599 return 0;
(gdb)
600 }
(gdb)
proc_symlink (name=name@entry=0xc15f0aec "mounts",
parent=0xc16abe20 <proc_root>, parent@entry=0x0,
dest=dest@entry=0xc15f0ae7 "self/mounts") at fs/proc/generic.c:664
664 }
(gdb)
- Create a symlink for /proc/net which links to /proc/self/net, register a network namespace subsystem
proc_root_init () at fs/proc/root.c:121
121 proc_net_init();
(gdb) s
proc_net_init () at fs/proc/proc_net.c:237
237 proc_symlink("net", NULL, "self/net");
(gdb) n
239 return register_pernet_subsys(&proc_net_ns_ops);
(gdb) s
register_pernet_subsys (ops=ops@entry=0xc173f838 <proc_net_ns_ops>)
at net/core/net_namespace.c:343
343 mutex_lock(&net_mutex);
(gdb) p *ops
$10 = {list = {next = 0x0, prev = 0x0}, init = 0xc1716f76 <proc_net_ns_init>,
exit = 0xc14643a0 <proc_net_ns_exit>}
(gdb) n
341 {
(gdb)
343 mutex_lock(&net_mutex);
(gdb)
344 error = register_pernet_operations(first_device, ops);
(gdb) p first_device
$11 = (struct list_head *) 0xc16d3bf4 <pernet_list>
(gdb) p *first_device
$12 = {next = 0xc16d3bf4 <pernet_list>, prev = 0xc16d3bf4 <pernet_list>}
(gdb) s
register_pernet_operations (list=0xc16d3bf4 <pernet_list>,
ops=0xc173f838 <proc_net_ns_ops>) at net/core/net_namespace.c:308
308 return 0;
(gdb) n
307 if (ops->init == NULL)
(gdb)
309 return ops->init(&init_net);
(gdb) s
proc_net_ns_init (net=0xc1f2a8c0 <init_net>) at fs/proc/proc_net.c:199
199 netd = kzalloc(sizeof(*netd), GFP_KERNEL);
(gdb) n
200 if (!netd)
(gdb)
203 netd->data = net;
(gdb)
204 netd->nlink = 2;
(gdb)
205 netd->name = "net";
(gdb)
206 netd->namelen = 3;
(gdb)
207 netd->parent = &proc_root;
(gdb)
210 net_statd = proc_net_mkdir(net, "stat", netd);
(gdb) s
proc_net_mkdir (net=net@entry=0xc1f2a8c0 <init_net>,
name=name@entry=0xc15dbc06 "stat", parent=parent@entry=0xc701f6e0)
at fs/proc/generic.c:683
683 {
(gdb) n
686 ent = __proc_create(&parent, name, S_IFDIR | S_IRUGO | S_IXUGO, 2);
(gdb) p parent
$13 = (struct proc_dir_entry *) 0xc701f6e0
(gdb) p *parent
$14 = {low_ino = 0, namelen = 3, name = 0xc15f1035 "net", mode = 0, nlink = 2,
uid = 0, gid = 0, size = 0, proc_iops = 0x0, proc_fops = 0x0, next = 0x0,
parent = 0xc16abe20 <proc_root>, subdir = 0x0, data = 0xc1f2a8c0 <init_net>,
read_proc = 0x0, write_proc = 0x0, count = {counter = 0}, pde_users = 0,
pde_unload_lock = {raw_lock = {slock = 0}, magic = 0, owner_cpu = 0,
owner = 0x0, dep_map = {key = 0x0, class_cache = 0x0, name = 0x0, cpu = 0,
ip = 0}}, pde_unload_completion = 0x0, pde_openers = {next = 0x0,
prev = 0x0}}
(gdb) n
687 if (ent) {
(gdb) p ent
$17 = (struct proc_dir_entry *) 0xc701f790
(gdb) p *ent
$18 = {low_ino = 0, namelen = 4, name = 0xc701f808 "stat", mode = 16749,
nlink = 2, uid = 0, gid = 0, size = 0, proc_iops = 0x0, proc_fops = 0x0,
next = 0x0, parent = 0x0, subdir = 0x0, data = 0x0, read_proc = 0x0,
write_proc = 0x0, count = {counter = 1}, pde_users = 0, pde_unload_lock = {
raw_lock = {slock = 0}, magic = 3735899821, owner_cpu = 4294967295,
owner = 0xffffffff, dep_map = {key = 0xc1e62b00 <__key.14684>,
class_cache = 0x0, name = 0xc15f0d6f "&ent->pde_unload_lock", cpu = 0,
ip = 0}}, pde_unload_completion = 0x0, pde_openers = {next = 0xc701f800,
prev = 0xc701f800}}
(gdb) n
688 ent->data = net;
(gdb)
689 if (proc_register(parent, ent) < 0) {
(gdb) s
proc_register (dir=0xc701f6e0, dp=dp@entry=0xc701f790) at fs/proc/generic.c:560
560 {
(gdb) n
564 i = get_inode_number();
(gdb)
569 if (S_ISDIR(dp->mode)) {
(gdb)
570 if (dp->proc_iops == NULL) {
(gdb)
571 dp->proc_fops = &proc_dir_operations;
(gdb)
572 dp->proc_iops = &proc_dir_inode_operations;
(gdb)
574 dir->nlink++;
(gdb)
585 spin_lock(&proc_subdir_lock);
(gdb)
587 for (tmp = dir->subdir; tmp; tmp = tmp->next)
(gdb)
594 dp->next = dir->subdir;
(gdb)
595 dp->parent = dir;
(gdb)
596 dir->subdir = dp;
(gdb)
597 spin_unlock(&proc_subdir_lock);
(gdb)
599 return 0;
(gdb)
600 }
(gdb)
proc_net_mkdir (net=net@entry=0xc1f2a8c0 <init_net>,
name=name@entry=0xc15dbc06 "stat", parent=parent@entry=0xc701f6e0)
at fs/proc/generic.c:695
695 }
(gdb)
proc_net_ns_init (net=0xc1f2a8c0 <init_net>) at fs/proc/proc_net.c:211
211 if (!net_statd)
(gdb)
214 net->proc_net = netd;
(gdb)
215 net->proc_net_stat = net_statd;
(gdb) p net_statd
$19 = (struct proc_dir_entry *) 0xc701f790
(gdb) p *net_statd
$20 = {low_ino = 4026531842, namelen = 4, name = 0xc701f808 "stat",
mode = 16749, nlink = 2, uid = 0, gid = 0, size = 0,
proc_iops = 0xc14a24c0 <proc_dir_inode_operations>,
proc_fops = 0xc14a2520 <proc_dir_operations>, next = 0x0,
parent = 0xc701f6e0, subdir = 0x0, data = 0xc1f2a8c0 <init_net>,
read_proc = 0x0, write_proc = 0x0, count = {counter = 1}, pde_users = 0,
pde_unload_lock = {raw_lock = {slock = 0}, magic = 3735899821,
owner_cpu = 4294967295, owner = 0xffffffff, dep_map = {
key = 0xc1e62b00 <__key.14684>, class_cache = 0x0,
name = 0xc15f0d6f "&ent->pde_unload_lock", cpu = 0, ip = 0}},
pde_unload_completion = 0x0, pde_openers = {next = 0xc701f800,
prev = 0xc701f800}}
(gdb) n
216 return 0;
(gdb)
222 }
(gdb)
register_pernet_subsys (ops=ops@entry=0xc173f838 <proc_net_ns_ops>)
at net/core/net_namespace.c:345
345 mutex_unlock(&net_mutex);
(gdb)
347 }
(gdb)
proc_net_init () at fs/proc/proc_net.c:240
240 }
(gdb)
- Creates /proc/sysvipc directory
proc_root_init () at fs/proc/root.c:124
124 proc_mkdir("sysvipc", NULL);
(gdb) s
proc_mkdir (name=name@entry=0xc15f0af3 "sysvipc", parent=parent@entry=0x0)
at fs/proc/generic.c:701
701 return proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent);
(gdb) s
proc_mkdir_mode (name=name@entry=0xc15f0af3 "sysvipc", mode=mode@entry=365,
parent=parent@entry=0x0) at fs/proc/generic.c:671
671 ent = __proc_create(&parent, name, S_IFDIR | mode, 2);
(gdb) s
__proc_create (parent=parent@entry=0xc168bfa4 <init_thread_union+8100>,
name=name@entry=0xc15f0af3 "sysvipc", mode=16749, nlink=nlink@entry=2)
at fs/proc/generic.c:606
606 {
(gdb) n
612 if (!name || !strlen(name)) goto out;
(gdb)
614 if (xlate_proc_name(name, parent, &fn) != 0)
(gdb)
618 if (strchr(fn, '/'))
(gdb)
621 len = strlen(fn);
(gdb) p fn
$21 = 0xc15f0af3 "sysvipc"
(gdb) n
623 ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
(gdb)
624 if (!ent) goto out;
(gdb)
626 memset(ent, 0, sizeof(struct proc_dir_entry));
(gdb)
627 memcpy(((char *) ent) + sizeof(struct proc_dir_entry), fn, len + 1);
(gdb)
628 ent->name = ((char *) ent) + sizeof(*ent);
(gdb)
629 ent->namelen = len;
(gdb)
630 ent->mode = mode;
(gdb)
631 ent->nlink = nlink;
(gdb)
632 atomic_set(&ent->count, 1);
(gdb)
633 ent->pde_users = 0;
(gdb)
634 spin_lock_init(&ent->pde_unload_lock);
(gdb)
635 ent->pde_unload_completion = NULL;
(gdb)
636 INIT_LIST_HEAD(&ent->pde_openers);
(gdb)
639 }
(gdb)
proc_mkdir_mode (name=name@entry=0xc15f0af3 "sysvipc", mode=mode@entry=365,
parent=0xc16abe20 <proc_root>, parent@entry=0x0) at fs/proc/generic.c:672
672 if (ent) {
(gdb)
673 if (proc_register(parent, ent) < 0) {
(gdb) p parent
$22 = (struct proc_dir_entry *) 0xc16abe20 <proc_root>
(gdb) p *parent
$23 = {low_ino = 1, namelen = 5, name = 0xc15f0b03 "/proc", mode = 16749,
nlink = 2, uid = 0, gid = 0, size = 0,
proc_iops = 0xc14a0ce0 <proc_root_inode_operations>,
proc_fops = 0xc14a0d40 <proc_root_operations>, next = 0x0,
parent = 0xc16abe20 <proc_root>, subdir = 0xc701f580, data = 0x0,
read_proc = 0x0, write_proc = 0x0, count = {counter = 2}, pde_users = 0,
pde_unload_lock = {raw_lock = {slock = 0}, magic = 0, owner_cpu = 0,
owner = 0x0, dep_map = {key = 0x0, class_cache = 0x0, name = 0x0, cpu = 0,
ip = 0}}, pde_unload_completion = 0x0, pde_openers = {next = 0x0,
prev = 0x0}}
(gdb) p ent
$24 = (struct proc_dir_entry *) 0xc701f840
(gdb) p *ent
$25 = {low_ino = 0, namelen = 7, name = 0xc701f8b8 "sysvipc", mode = 16749,
nlink = 2, uid = 0, gid = 0, size = 0, proc_iops = 0x0, proc_fops = 0x0,
next = 0x0, parent = 0x0, subdir = 0x0, data = 0x0, read_proc = 0x0,
write_proc = 0x0, count = {counter = 1}, pde_users = 0, pde_unload_lock = {
raw_lock = {slock = 0}, magic = 3735899821, owner_cpu = 4294967295,
owner = 0xffffffff, dep_map = {key = 0xc1e62b00 <__key.14684>,
class_cache = 0x0, name = 0xc15f0d6f "&ent->pde_unload_lock", cpu = 0,
ip = 0}}, pde_unload_completion = 0x0, pde_openers = {next = 0xc701f8b0,
prev = 0xc701f8b0}}
(gdb) s
proc_register (dir=0xc16abe20 <proc_root>, dp=dp@entry=0xc701f840)
at fs/proc/generic.c:560
560 {
(gdb) n
564 i = get_inode_number();
(gdb)
569 if (S_ISDIR(dp->mode)) {
(gdb)
570 if (dp->proc_iops == NULL) {
(gdb)
571 dp->proc_fops = &proc_dir_operations;
(gdb)
572 dp->proc_iops = &proc_dir_inode_operations;
(gdb)
574 dir->nlink++;
(gdb)
585 spin_lock(&proc_subdir_lock);
(gdb)
587 for (tmp = dir->subdir; tmp; tmp = tmp->next)
(gdb)
588 if (strcmp(tmp->name, dp->name) == 0) {
(gdb)
594 dp->next = dir->subdir;
(gdb)
595 dp->parent = dir;
(gdb)
596 dir->subdir = dp;
(gdb)
597 spin_unlock(&proc_subdir_lock);
(gdb)
599 return 0;
(gdb)
600 }
(gdb)
proc_mkdir_mode (name=name@entry=0xc15f0af3 "sysvipc", mode=mode@entry=365,
parent=0xc16abe20 <proc_root>, parent@entry=0x0) at fs/proc/generic.c:679
679 }
(gdb)
proc_mkdir (name=name@entry=0xc15f0af3 "sysvipc", parent=parent@entry=0x0)
at fs/proc/generic.c:702
702 }
(gdb)
- Creates /proc/fs
- Creates /proc/driver
- Creates /proc/fs/nfsd
proc_root_init () at fs/proc/root.c:126
126 proc_mkdir("fs", NULL);
(gdb)
127 proc_mkdir("driver", NULL);
(gdb)
128 proc_mkdir("fs/nfsd", NULL); /* somewhere for the nfsd filesystem to be mounted */
(gdb)
- Create the /proc/tty subtree
133 proc_tty_init();
(gdb) s
proc_tty_init () at fs/proc/proc_tty.c:177
177 if (!proc_mkdir("tty", NULL))
(gdb) n
179 proc_tty_ldisc = proc_mkdir("tty/ldisc", NULL);
(gdb)
186 proc_tty_driver = proc_mkdir_mode("tty/driver", S_IRUSR|S_IXUSR, NULL);
(gdb) s
proc_mkdir_mode (name=name@entry=0xc15f0f69 "tty/driver", mode=mode@entry=320,
parent=parent@entry=0x0) at fs/proc/generic.c:671
671 ent = __proc_create(&parent, name, S_IFDIR | mode, 2);
(gdb) n
672 if (ent) {
(gdb) p ent
$27 = (struct proc_dir_entry *) 0xc701fc60
(gdb) p *ent
$28 = {low_ino = 0, namelen = 6, name = 0xc701fcd8 "driver", mode = 16704,
nlink = 2, uid = 0, gid = 0, size = 0, proc_iops = 0x0, proc_fops = 0x0,
next = 0x0, parent = 0x0, subdir = 0x0, data = 0x0, read_proc = 0x0,
write_proc = 0x0, count = {counter = 1}, pde_users = 0, pde_unload_lock = {
raw_lock = {slock = 0}, magic = 3735899821, owner_cpu = 4294967295,
owner = 0xffffffff, dep_map = {key = 0xc1e62b00 <__key.14684>,
class_cache = 0x0, name = 0xc15f0d6f "&ent->pde_unload_lock", cpu = 0,
ip = 0}}, pde_unload_completion = 0x0, pde_openers = {next = 0xc701fcd0,
prev = 0xc701fcd0}}
(gdb) p parent
$29 = (struct proc_dir_entry *) 0xc701fb00
(gdb) p *parent
$30 = {low_ino = 4026531847, namelen = 3, name = 0xc701fb78 "tty",
mode = 16749, nlink = 3, uid = 0, gid = 0, size = 0,
proc_iops = 0xc14a24c0 <proc_dir_inode_operations>,
proc_fops = 0xc14a2520 <proc_dir_operations>, next = 0xc701f9a0,
parent = 0xc16abe20 <proc_root>, subdir = 0xc701fbb0, data = 0x0,
read_proc = 0x0, write_proc = 0x0, count = {counter = 1}, pde_users = 0,
pde_unload_lock = {raw_lock = {slock = 0}, magic = 3735899821,
owner_cpu = 4294967295, owner = 0xffffffff, dep_map = {
key = 0xc1e62b00 <__key.14684>, class_cache = 0x0,
name = 0xc15f0d6f "&ent->pde_unload_lock", cpu = 0, ip = 0}},
pde_unload_completion = 0x0, pde_openers = {next = 0xc701fb70,
prev = 0xc701fb70}}
(gdb) n
673 if (proc_register(parent, ent) < 0) {
(gdb) s
proc_register (dir=0xc701fb00, dp=dp@entry=0xc701fc60) at fs/proc/generic.c:560
560 {
(gdb) n
564 i = get_inode_number();
(gdb)
569 if (S_ISDIR(dp->mode)) {
(gdb)
570 if (dp->proc_iops == NULL) {
(gdb)
571 dp->proc_fops = &proc_dir_operations;
(gdb)
572 dp->proc_iops = &proc_dir_inode_operations;
(gdb)
574 dir->nlink++;
(gdb)
585 spin_lock(&proc_subdir_lock);
(gdb)
587 for (tmp = dir->subdir; tmp; tmp = tmp->next)
(gdb)
588 if (strcmp(tmp->name, dp->name) == 0) {
(gdb)
594 dp->next = dir->subdir;
(gdb)
595 dp->parent = dir;
(gdb)
596 dir->subdir = dp;
(gdb)
597 spin_unlock(&proc_subdir_lock);
(gdb)
599 return 0;
(gdb)
600 }
(gdb)
proc_mkdir_mode (name=name@entry=0xc15f0f69 "tty/driver", mode=mode@entry=320,
parent=0xc701fb00, parent@entry=0x0) at fs/proc/generic.c:679
679 }
(gdb)
proc_tty_init () at fs/proc/proc_tty.c:187
187 proc_create("tty/ldiscs", 0, NULL, &tty_ldiscs_proc_fops);
(gdb) s
proc_create (proc_fops=<optimized out>, parent=0x0, mode=0,
name=0xc15f0f74 "tty/ldiscs") at include/linux/proc_fs.h:155
155 return proc_create_data(name, mode, parent, proc_fops, NULL);
(gdb) s
proc_create_data (name=name@entry=0xc15f0f74 "tty/ldiscs", mode=mode@entry=0,
parent=parent@entry=0x0, proc_fops=0xc14bf580 <tty_ldiscs_proc_fops>,
data=data@entry=0x0) at fs/proc/generic.c:740
740 if (S_ISDIR(mode)) {
(gdb) n
736 {
(gdb)
740 if (S_ISDIR(mode)) {
(gdb)
746 mode |= S_IFREG;
(gdb)
747 if ((mode & S_IALLUGO) == 0)
(gdb)
748 mode |= S_IRUGO;
(gdb)
752 pde = __proc_create(&parent, name, mode, nlink);
(gdb)
753 if (!pde)
(gdb)
755 pde->proc_fops = proc_fops;
(gdb) p parent
$31 = (struct proc_dir_entry *) 0xc701fb00
(gdb) p *parent
$32 = {low_ino = 4026531847, namelen = 3, name = 0xc701fb78 "tty",
mode = 16749, nlink = 4, uid = 0, gid = 0, size = 0,
proc_iops = 0xc14a24c0 <proc_dir_inode_operations>,
proc_fops = 0xc14a2520 <proc_dir_operations>, next = 0xc701f9a0,
parent = 0xc16abe20 <proc_root>, subdir = 0xc701fc60, data = 0x0,
read_proc = 0x0, write_proc = 0x0, count = {counter = 1}, pde_users = 0,
pde_unload_lock = {raw_lock = {slock = 0}, magic = 3735899821,
owner_cpu = 4294967295, owner = 0xffffffff, dep_map = {
key = 0xc1e62b00 <__key.14684>, class_cache = 0x0,
name = 0xc15f0d6f "&ent->pde_unload_lock", cpu = 0, ip = 0}},
pde_unload_completion = 0x0, pde_openers = {next = 0xc701fb70,
prev = 0xc701fb70}}
(gdb) p *pde
$33 = {low_ino = 0, namelen = 6, name = 0xc701fd88 "ldiscs", mode = 33060,
nlink = 1, uid = 0, gid = 0, size = 0, proc_iops = 0x0, proc_fops = 0x0,
next = 0x0, parent = 0x0, subdir = 0x0, data = 0x0, read_proc = 0x0,
write_proc = 0x0, count = {counter = 1}, pde_users = 0, pde_unload_lock = {
raw_lock = {slock = 0}, magic = 3735899821, owner_cpu = 4294967295,
owner = 0xffffffff, dep_map = {key = 0xc1e62b00 <__key.14684>,
class_cache = 0x0, name = 0xc15f0d6f "&ent->pde_unload_lock", cpu = 0,
ip = 0}}, pde_unload_completion = 0x0, pde_openers = {next = 0xc701fd80,
prev = 0xc701fd80}}
(gdb) n
756 pde->data = data;
(gdb)
757 if (proc_register(parent, pde) < 0)
(gdb)
764 }
(gdb)
proc_tty_init () at fs/proc/proc_tty.c:189
189 }
(gdb)
- Creates /proc/bus
proc_root_init () at fs/proc/root.c:137
137 proc_mkdir("bus", NULL);
(gdb) n
- Creates /proc/sys
138 proc_sys_init();
(gdb) s
proc_sys_init () at fs/proc/proc_sysctl.c:409
409 proc_sys_root = proc_mkdir("sys", NULL);
(gdb) n
410 proc_sys_root->proc_iops = &proc_sys_dir_operations;
(gdb)
411 proc_sys_root->proc_fops = &proc_sys_dir_file_operations;
(gdb)
412 proc_sys_root->nlink = 0;
(gdb)
414 }
(gdb)
proc_root_init () at fs/proc/root.c:139
139 }
(gdb)